package body communautes.generic_implementation is



   -------------------------------------------------------------------------------------------
   ------------------------------------La communaute------------------------------------------
   -------------------------------------------------------------------------------------------

   function creer return communaute is
   begin
      return (communautes.communaute with content => Creer);
   end creer;



   -------------------------------------------------------------------------------------------
   ---------------------------------Les individus de la communaute----------------------------
   -------------------------------------------------------------------------------------------


   function inscrire(C0:communaute; I1:individu) return communaute is
      pragma Assert (not est_inscrit(C0,I1));
   begin
      return (communautes.communaute with content => inscrire(communaute(C0).Content, I1));
   end inscrire;

   function est_inscrit(C0:communaute;I1:individu) return boolean is
   begin
      return est_inscrit (communaute(C0).Content,I1);
   end est_inscrit;

   function nombre_inscrit(C0:communaute) return natural is
   begin
      return nombre_inscrit (communaute(C0).Content);
   end nombre_inscrit;


   function ieme_inscrit(C0:communaute;I:Natural) return individu is
      pragma Assert (1<=I AND i<= nombre_inscrit(C0));
   begin
      return ieme_inscrit (communaute(C0).Content,I);
   end ieme_inscrit;



   function bloquer (C0:communaute; I1,I2: individu) return communaute is
      pragma Assert(est_inscrit(C0,I1) AND
                      est_inscrit(C0,I2) AND
                      not est_bloque(C0,I1,I2) AND
                      not (I1=I2));

   begin
      return (communautes.communaute with content => bloquer(communaute(C0).Content, I1,I2));
   end bloquer;

   function debloquer (C0:communaute; I1,I2: individu) return communaute is
      pragma Assert(est_inscrit(C0,I1) AND est_inscrit(C0,I2) AND est_bloque (C0,I1,I2));
   begin
      return (communautes.communaute with content => debloquer(communaute(C0).Content, I1,I2));
   end debloquer;

   function est_bloque(C0:communaute; I1,I2:individu) return boolean is
   begin
      return est_bloque (communaute(C0).Content,I1,I2);
   end est_bloque;


   -------------------------------------------------------------------------------------------
   -----------------------------------Les cercles d'un individu-------------------------------
   -------------------------------------------------------------------------------------------


   function ajouter_cercle(C0:communaute; I1: individu; C1:cercle) return communaute  is
      Pragma Assert(est_inscrit(C0,I1) AND not est_cercle_de(C0,I1,C1));
   begin
      return (communautes.communaute with content => ajouter_cercle(communaute(C0).Content, I1,C1));
   end ajouter_cercle;

   function retirer_cercle(C0:communaute; I1: individu; C1:cercle) return communaute is
      Pragma Assert(est_inscrit(C0,I1) AND est_cercle_de(C0,I1,C1));
   begin
      return (communautes.communaute with content => retirer_cercle(communaute(C0).Content, I1,C1));
   end retirer_cercle;

   function ieme_cercle(C0:communaute;I1:individu;I:natural) return cercle is
      Pragma Assert(est_inscrit(C0,I1) AND 1<=I AND i<= nombre_cercle_de(C0,I1));
   begin
      return ieme_cercle(communaute(C0).Content,I1,I);
   end ieme_cercle;

   function est_cercle_de(C0:communaute;I1:individu;C1:cercle) return boolean is
   begin
      return est_cercle_de (communaute(C0).Content,I1,C1);
   end est_cercle_de;

   function nombre_cercle_de(C0:communaute;I1:individu) return Natural is
   begin
      return nombre_cercle_de (communaute(C0).Content,I1);
   end nombre_cercle_de;


   -------------------------------------------------------------------------------------------
   ----------------------------------Les membres d'un cercle----------------------------------
   -------------------------------------------------------------------------------------------


   function ajouter_membre(C0:communaute; I1: individu; C1:cercle; I2: individu) return communaute is
      pragma Assert(est_inscrit(C0,I1) AND
                      est_inscrit(C0,I2) AND
                      est_cercle_de(C0,I1,C1) AND
                      not est_membre_de(C0,I1,C1,I2) AND
                      not (I1=I2) AND
                      not est_bloque(C0,I1,I2));
   begin
      return (communautes.communaute with content => ajouter_membre(communaute(C0).Content, I1,C1,I2));
   end ajouter_membre;

   function retirer_membre(C0:communaute; I1: individu; C1:cercle; I2: individu) return communaute is
   pragma Assert(est_inscrit(C0,I1) AND
                      est_inscrit(C0,I2) AND
                      est_cercle_de(C0,I1,C1) AND
                      est_membre_de(C0,I1,C1,I2));
   begin
      return (communautes.communaute with content => retirer_membre(communaute(C0).Content, I1,C1,I2));
   end retirer_membre;

   function nombre_membre_de(C0:communaute;I1:individu;C1:cercle)return natural is
   begin
      return nombre_membre_de(communaute(C0).Content,I1,C1);
   end nombre_membre_de;

   function est_membre_de(C0:communaute;I1:individu;C1:cercle;I2:individu) return boolean is
   begin
      return est_membre_de (communaute(C0).Content,I1,C1,I2);
   end est_membre_de;

   function ieme_membre(C0:communaute;I1:individu;C1:cercle;I:natural)return individu is
      Pragma Assert(est_inscrit(C0,I1) AND
                      est_cercle_de(C0,I1,C1) AND
                      1<=I AND
                      i<= nombre_membre_de(C0,I1,C1)
                   );
   begin
      return ieme_membre(communaute(C0).Content,I1,C1,I);
   end ieme_membre;

   -------------------------------------------------------------------------------------------
   --------------------------------Les Posts et commentaires----------------------------------
   -------------------------------------------------------------------------------------------

   function poster(C0:communaute;I1:individu;C1:cercle;t: message) return communaute is
   Pragma Assert(est_inscrit (C0, I1) AND est_cercle_de (C0, I1,C1));
   begin
      return (communautes.communaute with content => poster(communaute(C0).Content, I1,C1,t));
   end poster;

   function commenter(C0: communaute; I1:individu; I:Natural; T: message) return communaute is
   Pragma Assert(est_inscrit (C0, I1) AND est_defini (consulter (C0, I1), I));
   begin
      return (communautes.communaute with content => commenter(communaute(C0).Content, I1,I,T));
   end commenter;

   function consulter(C0:communaute;I1:individu) return Mur is
   Pragma Assert(est_inscrit(C0,I1));
   begin
      return consulter(communaute(C0).Content,I1);
   end consulter;

   function nombre_post(C0:communaute) return Natural is
   begin
      return nombre_post(communaute(C0).Content);
   end nombre_post;


end communautes.generic_implementation;
